﻿//Copyright (C) 2009  Jaco (ScionBot.com)

//This program is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Scion.Library;
using Scion.Library.Underlying;
using System.Drawing;
using Scion.Library.Antiban;

namespace Scion.Library.RS.UI
{
    /// <summary>
    /// Contains bank methods to deposit/withdraw your items anywhere in RS.
    /// </summary>
    public class Bank : Determine
    {
        Superior super;
        BankLocation location;

        Color bankCol;
        int tol = -1;

        /// <summary>
        /// Opens a bank anywhere in RS.
        /// </summary>
        /// <param name="s">The instance of the bot.</param>
        /// <param name="bl">The bank you want to open.</param>
        public Bank(Superior s, BankLocation bl)
        {
            super = s;
            location = bl;
        }

        public Bank(Superior s, Color bankC, int t)
        {
            super = s;
            bankCol = bankC;
            tol = t;
        }

        /// <summary>
        /// Figures out if the bank is open or not.
        /// </summary>
        /// <returns>Returns true if the bank is open.</returns>
        public bool BankOpen()
        {
            if (Decide(super.FindText(new Rectangle(20, 22, 400, 45), "Bank", Scion.Library.Advanced.CharFont.UpChars, new Color[] { super.FromRGB(242, 170, 62) }, 20, 30)))
                return true;
            return false;
        }

        /// <summary>
        /// Withdraws anything out of the bank.
        /// </summary>
        /// <param name="item">The item to search for.</param>
        /// <param name="itemToptext">The top text of the item.</param>
        /// <param name="quantity">How many items to withdraw.</param>
        /// <returns>Returns true if the function succeeded.</returns>
        public bool Withdraw(string item, string itemToptext, int quantity)
        {
            if (!BankOpen())
                return false;
            SizeRandom sr = new SizeRandom(new Size(98 - 70, 316 - 298), new Point(70, 298));
            super.Mouse.MoveClick(new PointRandom(sr.random.X, sr.random.Y, 0), true);
            while (!super.ChatText.FindText(ChatText.Chatbox, Scion.Library.Advanced.CharFont.UpChars, "search"))
                super.Sleep(new SleepRandom(1000, 1100));
            if (super.ChatText.FindText(ChatText.Chatbox, Scion.Library.Advanced.CharFont.UpChars, "search"))
            {
                super.Keyboard.Type(item, new TypeRandom(150, 25));
                super.Keyboard.PressEnter(new SleepRandom(20, 50));
            }
            else
                return false;
            super.Sleep(new SleepRandom(2000, 3000));
            int xRelative = 32;
            int yRelative = 90;
            for (int y = 1; y < 6; y++)
            {
                for (int x = 1; x < 11; x++)
                {
                    SizeRandom sr2 = new SizeRandom(new Size(43 - 30, 43 - 30), new Point(xRelative + 20, yRelative + 20));
                    super.Mouse.MoveMouse(new PointRandom(sr2.random.X, sr2.random.Y, 0));
                    super.Sleep(new SleepRandom(200, 300));
                    if (super.TopText.FindText(TopText.Common, itemToptext, TopText.Tolerance))
                    {
                        if (quantity == 1)
                            return super.Mouse.ClickMouse(new PointRandom(super.Mouse.CurrentX, super.Mouse.CurrentY, 0), true);
                        super.Mouse.ClickMouse(new PointRandom(super.Mouse.CurrentX, super.Mouse.CurrentY, 0), false);
                        super.Sleep(new SleepRandom(300, 400));
                        ChooseOption so = new ChooseOption(super);
                        bool result = false;
                        if (quantity == 0)
                            result = so.DoAction(ChooseOption.Common, "-All");
                        else
                        {
                            result = so.DoAction(ChooseOption.Common, "-X");
                            while (!Decide(super.FindColour(Areas.ChatScreenBounds, Color.FromArgb(0, 0, 128), 2)))
                                super.Sleep(new SleepRandom(400, 500));
                            super.Keyboard.Type(quantity.ToString(), new TypeRandom(200, 50));
                            super.Sleep(new SleepRandom(100, 200));
                            return super.Keyboard.PressEnter(new SleepRandom(20, 40));
                        }
                        if (result == false) return false;
                        else return true;
                    }
                    xRelative += 43;
                }
                xRelative = 32;
                yRelative += 43;
            }
            return false;
        }

        /// <summary>
        /// Deposits all the items in the bank.
        /// </summary>
        /// <param name="item">The top text of the item.</param>
        /// <returns>Returns true if the function succeeded.</returns>
        public bool DepositAll(string item)
        {
            if (!BankOpen())
                return false;
            Inventory i = new Inventory(super);
            PointRandom pr = i.FindItem(item);
            if (pr.random.X == -1) return false;
            return i.DoAction(pr, "-All", ChooseOption.Common);
        }

        /// <summary>
        /// Deposists an item in the bank with the specified quantity.
        /// </summary>
        /// <param name="item">The top text of the item.</param>
        /// <param name="quantity">How many to store in bank.</param>
        /// <returns>Returns true if the function succeeded.</returns>
        public bool Deposit(string item, int quantity)
        {
            if (!BankOpen())
                return false;
            Inventory i = new Inventory(super);
            PointRandom pr = i.FindItem(item);
            if (pr.random.X == -1) return false;
            if (quantity == 1)
                return i.DoAction(pr, "", ChooseOption.Common);
            bool result = i.DoAction(pr, "-X", ChooseOption.Common);
            if (!result) return false;
            while (!Decide(super.FindColour(Areas.ChatScreenBounds, Color.FromArgb(0, 0, 128), 2)))
                super.Sleep(new SleepRandom(400, 500));
            super.Keyboard.Type(quantity.ToString(), new TypeRandom(200, 50));
            super.Sleep(new SleepRandom(100, 200));
            return super.Keyboard.PressEnter(new SleepRandom(20,40));
        }

        /// <summary>
        /// Closes the bank.
        /// </summary>
        public void Close()
        {
            super.Sleep(new SleepRandom(1000, 2000));
            SizeRandom size = new SizeRandom(new Size(10, 12), new Point(483, 28));
            super.Mouse.MoveClick(new PointRandom(size.random.X, size.random.Y, 0), true);
            while (BankOpen())
                super.Sleep(new SleepRandom(1000, 1200));
        }

        /// <summary>
        /// Locates the bank and opens it.
        /// </summary>
        /// <returns>Returns true if the bank was successfully opened.</returns>
        public bool Open()
        {
            Color bankColour;
            int tolerance;
            if (tol != -1)
            {
                bankColour = bankCol;
                tolerance = tol;
            }
            else
            {
                bankColour = DetermineColour(location);
                tolerance = DetermineTolerance(location);
            }
            RSObject bankBooth = new RSObject(super, Areas.CharacterCentre, bankColour, "ooth", Areas.WorldBounds, tolerance, 3);
            bool result = bankBooth.DoAction("uickly", ChooseOption.Common);
            while (!BankOpen())
                super.Sleep(new SleepRandom(1000, 1200));
            if (result)
                return true;
            return false;
        }

        private int DetermineTolerance(BankLocation bl)
        {
            switch (bl)
            {
                case BankLocation.Al_Kharid:
                    return 25;
                case BankLocation.Lumbridge:
                    return 10;
                case BankLocation.VarrockEast:
                    return 10;
                case BankLocation.VarrockWest:
                    return 25;
                case BankLocation.FaladorEast:
                    return 14;
                case BankLocation.FaladorWest:
                    return 14;
                case BankLocation.Draynor:
                    return 4;
                case BankLocation.EdgevilleBank:
                    return 9;
            }
            return -1;
        }

        private Color DetermineColour(BankLocation bl)
        {
            switch (bl)
            {
                case BankLocation.Al_Kharid:
                    return Color.FromArgb(179, 153, 121);
                case BankLocation.Lumbridge:
                    return Color.FromArgb(108, 92, 73);
                case BankLocation.VarrockEast:
                    return Color.FromArgb(100, 86, 45);
                case BankLocation.VarrockWest:
                    return Color.FromArgb(230, 207, 86);
                case BankLocation.FaladorEast:
                    return Color.FromArgb(120, 98, 70);
                case BankLocation.FaladorWest:
                    return Color.FromArgb(120, 98, 70);
                case BankLocation.Draynor:
                    return Color.FromArgb(78, 59, 9);
                case BankLocation.EdgevilleBank:
                    return Color.FromArgb(87, 74, 49);
            }
            return Color.FromArgb(0,0,0);
        }
    }

    /// <summary>
    /// Which bank to use.
    /// </summary>
    public enum BankLocation
    {
        Al_Kharid = 1,
        Lumbridge = 2,
        VarrockEast = 3,
        VarrockWest = 4,
        FaladorEast = 5,
        FaladorWest = 6,
        Draynor = 7,
        EdgevilleBank = 8,
    }
}
